
from PyQt5.QtCore import QSize, pyqtProperty, QTimer, Qt, pyqtSignal,QCoreApplication
from PyQt5.QtGui import QColor, QPainter,QCloseEvent,QCursor,QPixmap,QMovie
from PyQt5.QtWidgets import QWidget, QHBoxLayout,QMessageBox,QMenu,QLabel,QVBoxLayout


from PyQt5.QtNetwork import QLocalSocket, QLocalServer
from PyQt5.QtWidgets import QApplication



class popup(QWidget):

    def __init__(self):
        QWidget.__init__(self)
        self.angle = 0
        self.Color = QColor(24, 189, 155)
        self.setWindowFlags(Qt.FramelessWindowHint)
        self.setAttribute(Qt.WA_TranslucentBackground)
        self._timer = QTimer(self, timeout=self.update)

    def paintEvent(self, event):
        super(popup, self).paintEvent(event)
        painter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing)
        painter.translate(self.width() / 2, self.height() / 2)
        side = min(self.width(), self.height())
        painter.scale(side / 300.0, side / 300.0)
        painter.rotate(self.angle)
        painter.save()
        painter.setPen(Qt.NoPen)
        color = self.Color.toRgb()
        for i in range(11):
            color.setAlphaF(1.0 * i / 10)
            painter.setBrush(color)
            painter.drawEllipse(30, -10, 20, 20)
            painter.rotate(36)
        painter.restore()
        self.angle += 36
        self.angle %= 360

    def _stop(self):
        self.hide()
        self._timer.stop()

    def _start(self,x,y):
        self.move(x,y)
        self._timer.start(50)
        self.show()

    def _update(self,size,x,y):
        self.resize(size)
        self.move(x,y)
        self.raise_()



class My_QMessageBox(QMessageBox):

    def __init__(self,code,codes,windows):
        super(My_QMessageBox, self).__init__(windows)
        self.setWindowTitle(code)
        self.setText(codes)
        self.setIcon(QMessageBox.Information)
        self.addButton("确定", QMessageBox.YesRole)



class MessageBox(QMessageBox):

    def __init__(self, *args, count=5, title=" ", auto=False, **kwargs):
        super(MessageBox, self).__init__(*args, **kwargs)
        self.setWindowTitle(title)
        self._count = count
        self._auto = auto
        self.closeBtn0 = self.addButton("是", QMessageBox.YesRole)
        self.closeBtn1 = self.addButton("否", QMessageBox.NoRole)
        self.closeBtn0.setText('({})'.format(self._count))
        self.closeBtn0.setEnabled(False)
        self._timer = QTimer(self, timeout=self.doCountDown)
        self._timer.start(700)

    def doCountDown(self):
        self.closeBtn0.setText('({})'.format(self._count))
        self._count -= 1
        if self._count == 0:
            self.closeBtn0.setText('是')
            self.closeBtn0.setEnabled(True)
            self._timer.stop()
            if self._auto:
                self.accept()
                self.close()



class QSingleApplication(QApplication):
    
    messageReceived = pyqtSignal(str)
    
    def __init__(self, *args, **kwargs):
        super(QSingleApplication, self).__init__(*args, **kwargs)
        appid = QApplication.applicationFilePath().lower().split("/")[-1]
        self._socketName = "qtsingleapp-" + appid
        print("socketName", self._socketName)
        self._activationWindow = None
        self._activateOnMessage = False
        self._socketServer = None
        self._socketIn = None
        self._socketOut = None
        self._running = False
        
        # 先尝试连接
        self._socketOut = QLocalSocket(self)
        self._socketOut.connectToServer(self._socketName)
        self._socketOut.error.connect(self.handleError)
        self._running = self._socketOut.waitForConnected()
        
        if not self._running:  # 程序未运行
            self._socketOut.close()
            del self._socketOut
            self._socketServer = QLocalServer(self)
            self._socketServer.listen(self._socketName)
            self._socketServer.newConnection.connect(self._onNewConnection)
            self.aboutToQuit.connect(self.removeServer)
    
    def handleError(self, message):
        pass
    
    def isRunning(self):
        return self._running
    
    def activationWindow(self):
        return self._activationWindow
    
    def setActivationWindow(self, activationWindow, activateOnMessage=True):
        self._activationWindow = activationWindow
        self._activateOnMessage = activateOnMessage
    
    def activateWindow(self):
        if not self._activationWindow:
            return
        self._activationWindow.setWindowState(
            self._activationWindow.windowState() & ~Qt.WindowMinimized)
        self._activationWindow.raise_()
        self._activationWindow.activateWindow()
    
    def sendMessage(self, message, msecs=5000):
        if not self._socketOut:
            return False
        if not isinstance(message, bytes):
            message = str(message).encode()
        self._socketOut.write(message)
        if not self._socketOut.waitForBytesWritten(msecs):
            raise RuntimeError("Bytes not written within %ss" % (msecs / 1000.))
        return True
    
    def _onNewConnection(self):
        if self._socketIn:
            self._socketIn.readyRead.disconnect(self._onReadyRead)
        self._socketIn = self._socketServer.nextPendingConnection()
        if not self._socketIn:
            return
        self._socketIn.readyRead.connect(self._onReadyRead)
        if self._activateOnMessage:
            self.activateWindow()
    
    def _onReadyRead(self):
        while 1:
            message = self._socketIn.readLine()
            if not message:
                break
            #print("Message received: ", message)
            self.messageReceived.emit(message.data().decode())

    def removeServer(self):
        self._socketServer.close()
        self._socketServer.removeServer(self._socketName)



class menu(QMenu):
    def __init__(self, per, windos, table, call, *arg):
        super(menu, self).__init__(per)
        for k,v in enumerate(table):
            self.add_acton(k, v, call, *arg)
        self.setCursor(QCursor(windos.icon))

    def add_acton(self, k, v, call, *arg):
        self.addAction(v).triggered.connect(lambda : call(k, *arg))

